package com.landmark;

import java.awt.EventQueue;
import java.io.FileWriter;
import java.net.ConnectException;
import java.net.SocketTimeoutException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Enumeration;
import java.util.Hashtable;
import javax.swing.JTextArea;
import javax.swing.SwingWorker;
import org.htmlparser.Parser;
import org.htmlparser.util.NodeList;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

public class ForensicSource extends SwingWorker<Boolean, Boolean> {

    FileWriter fw = null;
    FileWriter errorFile = null;
    int pageNo;
    StringBuffer sb = new StringBuffer();
    Hashtable<String, String> htModelLinks = new Hashtable<String, String>();
    Hashtable<String, String> htMainCategories = new Hashtable<String, String>();
    Hashtable<String, String> htSubCategories = new Hashtable<String, String>();
    String status = "";
    JTextArea txtArea;
    UMProgressBar pBar = null;
    int lineCount = 0;

    @Override
    protected Boolean doInBackground() throws Exception {
        start();
        return true;
    }

    @Override
    protected void done() {
        Util.taskCompleteMsg(status);
    }

    public void start() {
        try {
            String dirName = "./outputs";
            String imagesPath = "./outputs/ForensicImages";
            String barcoSwatchesPath = "./outputs/ForensicSwatches";

            Util.createDirectory(dirName);
            Util.createDirectory(imagesPath);
            Util.createDirectory(barcoSwatchesPath);

            txtArea = Util.createOutputFile("ForensicSource");
            HelperBean helperBean = Util.getHelperBean();

            fw = new FileWriter(helperBean.getOutputFile());
            errorFile = new FileWriter(helperBean.getErrorFile());
            getMainCategories("http://www.forensicssource.com/Default.aspx");

            Enumeration enume = htMainCategories.keys();
            while (enume.hasMoreElements()) {
                String url = (String) enume.nextElement();
                getSubcategories(url);
            }
            System.out.println(htSubCategories.size());

            Enumeration enumeSub = htSubCategories.keys();
            lineCount = 0;
            pBar = new UMProgressBar();
            Util.getHelperBean().setLineCount(htSubCategories.size());
            while (enumeSub.hasMoreElements()) {
                String url = (String) enumeSub.nextElement();
                Util.getHelperBean().setCurrentCount(lineCount++);
                getProductUrls(url);
                EventQueue.invokeLater(pBar);
                if (Util.getHelperBean().getLineCount() == lineCount) {
                    Util.getHelperBean().setProcessingDone(true);
                    pBar.close();
                }
            }
            txtArea.append("\nFiles are located at : \n" + helperBean.getOutputFile().getAbsolutePath() + "\n" + helperBean.getErrorFile().getAbsolutePath() + "\n");
            txtArea.append("Total products : " + htModelLinks.size() + "\n");
            txtArea.paintImmediately(txtArea.getVisibleRect());
            Util.getHelperBean().setLineCount(htModelLinks.size());

            iterateCollection(htModelLinks);

            if (fw != null) {
                fw.close();
            }

        } catch (Exception e) {
            status = e.toString();
        } finally {
            try {
                if (fw != null) {
                    fw.close();
                }
            } catch (Exception e1) {
                // TODO: handle exception
            }
        }
        status = status.trim().equals("") ? "Done processing." : status;
        if (Util.getHelperBean().isTerminateCurrentProcess()) {
            status = "Process Terminated";
        }
        txtArea.append("\n" + status);
    }

    /**
     *
     * @param htLinks
     */
    private void iterateCollection(Hashtable<String, String> htLinks) throws Exception {
        lineCount = 0;
        if( pBar.isActive() || pBar.isShowing() ) {
            pBar.close();
        }
        pBar = new UMProgressBar();
        Enumeration<String> keys = htLinks.keys();
        fw.write("Category,ItemNumber,Product_Name, Description\n");
        while (keys.hasMoreElements()) {
            if (Util.getHelperBean().isTerminateCurrentProcess()) {
                break;
            }
            String key = (String) keys.nextElement();
            txtArea.append("Processing page: " + key + "\n");
            txtArea.paintImmediately(txtArea.getVisibleRect());
            sb = new StringBuffer();
            Util.getHelperBean().setCurrentCount(lineCount++);

            processModels(htLinks.get(key).toString());
            fw.write(sb.toString().replaceAll("\n", "").replace("   ", "").replaceAll("<#NEWLINE#>", "\n"));
            fw.write("\n");
            fw.flush();
            EventQueue.invokeLater(pBar);
            if (Util.getHelperBean().getLineCount() == lineCount) {
                Util.getHelperBean().setProcessingDone(true);
                pBar.close();
            }
        }
    }

    /**
     *
     * @param aUrl
     */
    private void processModels(String aUrl) throws Exception {
        try {
            Parser parser = Util.getParserFromUrl(aUrl, null);
            NodeList nl = parser.parse(null);
            System.out.println(aUrl);
            String prdtNameLs = Util.getHelperBean().getInputHTML().select("div.content2").select("h1").text();
            Elements category = Util.getHelperBean().getInputHTML().select("div.contentArea").select(".bcbar").select("a");
            String categoryPath = "";
            for (Element ele : category) {
                categoryPath += ele.text() + ">";
            }
            String itemNumber = Util.getHelperBean().getInputHTML().select("div.content2").select("h2").select("td").text();
            System.out.println(itemNumber);
            String prdtDescStr = Util.getHelperBean().getInputHTML().select("div.content2").select("div.product-desc").select("div:has(p)").html();
            sb.append(categoryPath.replaceAll(",", "::"));
            sb.append(",");
            sb.append(itemNumber);
            sb.append(",");
            sb.append(prdtNameLs.replaceAll(",", "#44;"));
            sb.append(",");
            if( !prdtDescStr.equals("")) {
                prdtDescStr = prdtDescStr.replaceAll(",", "#44;").replace("Tell a Friend Zoom ", "").replaceAll("”", "\"");
                sb.append(prdtDescStr.substring(prdtDescStr.indexOf("<p>"), prdtDescStr.lastIndexOf("</p>")).replace("<div>", "").replace("</div>", ""));
            }
            sb.append("<#NEWLINE#>");
        } catch (SocketTimeoutException e) {
            try {
                processModels(aUrl);
            } catch (Exception e1) {
            }
        } catch (ConnectException e) {
            try {
                processModels(aUrl);
            } catch (Exception e1) {
            }
        }
    }

    private void getProductUrls(String aUrl) throws Exception {
        try {
            Document doc = Jsoup.connect(aUrl).get();
            Elements elements = doc.select("div.product-info").select("a[href]");
            System.out.println(elements.size());
            for (Element element : elements) {
                String absoluteUrl = element.attr("abs:href");
                if (absoluteUrl.contains("ProductName=")) {
                    htModelLinks.put(absoluteUrl, absoluteUrl);
                }
            }
        } catch (SocketTimeoutException e) {
            try {
                getProductUrls(aUrl);
            } catch (Exception e1) {
            }
        } catch (ConnectException e) {
            try {
                getProductUrls(aUrl);
            } catch (Exception e1) {
            }
        }
    }

    private void getMainCategories(String aUrl) throws Exception {
        try {
            Document doc = Jsoup.connect(aUrl).get();
            Elements elements = doc.select("div.ln-2").select("a[href]");
            System.out.println(elements.size());
            for (Element element : elements) {
                String absoluteUrl = element.attr("abs:href");
                htMainCategories.put(absoluteUrl, absoluteUrl);
            }
        } catch (SocketTimeoutException e) {
            try {
                getMainCategories(aUrl);
            } catch (Exception e1) {
            }
        } catch (ConnectException e) {
            try {
                getMainCategories(aUrl);
            } catch (Exception e1) {
            }
        }
    }

    private void getSubcategories(String aUrl) throws Exception {
        try {
            Document doc = Jsoup.connect(aUrl).get();
            Elements elements = doc.select("div.product-info").select("a[href]");
            for (Element element : elements) {
                String absoluteUrl = element.attr("abs:href");
                htSubCategories.put(absoluteUrl, absoluteUrl);

            }
        } catch (SocketTimeoutException e) {
            try {
                getSubcategories(aUrl);
            } catch (Exception e1) {
            }
        } catch (ConnectException e) {
            try {
                getSubcategories(aUrl);
            } catch (Exception e1) {
            }
        }
    }
}
